/******************************************************************************
*
* This file is part of FreeTrack (http://code.google.com/p/qtfreetrack).
* BY Willy Gardiol (willy@gardiol.org)
*
* FreeTrack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FreeTrack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar.  If not, see <http://www.gnu.org/licenses/>
*
******************************************************************************/

#include "workerautoload.h"
#include "livetrackautosaver.h"
#include "livetrack.h"

WorkerAutoLoad::WorkerAutoLoad(QFile* f, LiveTrack* t ) :
    WorkerProcess(1, tr("Restoring LiveTrack..."))
{
    file = f;
    livetrack = t;
}

bool WorkerAutoLoad::do_stuff()
{
    if ( !file->isReadable() )
    {
        setErrorString( tr("File is not open"));
        return false;
    }

    GPS_track* track = livetrack->_track;
    QTextStream stream( file );
    int file_size = file->size();
    setMinMaxProgress( file_size );
    updateText(0, tr("Restoring autosave...") );
    updateProgress(0);
    QString what;

    int last_active_leg = -1;
    QHash<int, int> legs_match;
    QHash<int, int> waypoints_match;

    while ( !stream.atEnd() )
    {
        stream >> what;
        if ( what == AS_TITLE )
        {
            track->setTitle( LiveTrackAutosaver::readString( stream ) );
        }

        else if ( what == AS_DESC )
        {
            track->setDescription( LiveTrackAutosaver::readString( stream ) );
        }

        else if ( what == AS_POINT )
        {
            int leg_id;
            GPS_point* new_point = LiveTrackAutosaver::readPoint(stream, leg_id );
            if ( !track->addPointToLeg( new_point, legs_match.value( leg_id, last_active_leg ) ) )
                delete new_point;
        }

        else if ( what == AS_WAYPOINT )
        {
            int old_id = LiveTrackAutosaver::readId(stream);
            GPS_waypoint* new_waypoint = NULL;
            // Do we already have it?
            if ( !waypoints_match.contains( old_id ) )
            {
                // No, its new, so load entirely
                new_waypoint = LiveTrackAutosaver::readWaypoint( stream );
                waypoints_match.insert( old_id, new_waypoint->id() );
            }
            else
            { // Get the real waypoint...
                new_waypoint = track->waypointMod( waypoints_match.value( old_id ));
                // Copy the updated waypoint data to the real waypoint:
                LiveTrackAutosaver::readWaypoint( stream, new_waypoint );
            }
            track->waypointUpdated( new_waypoint );
        }

        else if ( what == AS_BACK )
        {
            track->dropLastPointFromLeg( legs_match.value( LiveTrackAutosaver::readId(stream), -1 ) );
        }

        else if ( what ==  AS_LEG )
        {
            int old_id = LiveTrackAutosaver::readId(stream);
            GPS_leg* new_leg = NULL;
            // Do we have already created this leg?
            if ( !legs_match.contains( old_id ) )
            {
                 new_leg = LiveTrackAutosaver::readLeg(stream);
                // No, add the match...
                legs_match.insert( old_id, new_leg->id() );
            }
            else
            {
                // Get the real leg from the track:
                new_leg = track->legMod( legs_match.value( old_id ) );
                LiveTrackAutosaver::readLeg(stream, new_leg );
            }
            track->legUpdated( new_leg );
        }

        else if ( what == AS_ACTIVE_LEG )
        {
            int new_active_leg = LiveTrackAutosaver::readId(stream);
            // Do we have already created this leg?
            if ( (new_active_leg > -1) && (legs_match.contains( new_active_leg )) )
            {
                int leg_id = legs_match.value( new_active_leg );
                livetrack->_activeLeg = last_active_leg = leg_id;
            }
        }

        else if ( what == AS_FILENAME )
        {
            livetrack->_filename = LiveTrackAutosaver::readString(stream);
        }

        else if ( what == AS_DELETE_LEG )
        {
            int old_id = LiveTrackAutosaver::readId( stream );
            if ( legs_match.contains( old_id ) )
                track->deleteLeg( legs_match.value( old_id ) );
        }

        else if ( what == AS_DELETE_WAYPOINT )
        {
            int old_id = LiveTrackAutosaver::readId(stream);
            if ( waypoints_match.contains( old_id ) )
                track->deleteWaypoint( waypoints_match.value( old_id ) );
        }

        else if ( !stream.atEnd() )
        {
            setErrorString( tr("Autosave is invalid!") + QString("code: '%1'").arg(what) );
            return false;
        }

        updateProgress( file->pos() );
        if ( please_terminate )
            return false;
    }
    updateText(0, tr("LiveTrack restored!") );
    updateProgress( file->pos() );
    return true;
}
